#include<stdio.h>

#define TAMANHO 5

typedef struct cliente{
    int codigo;
    char nome [50];
}Cliente;

typedef struct imovel{
    int codigo;
    char nome [50];
    float preco;
}Imovel;

typedef struct venda{
    int codigo_cliente;
    int codigo_imovel;
    float entrada;
}Venda;

Cliente clientes[TAMANHO];
Imovel imoveis[TAMANHO];
Venda vendas[TAMANHO];

int indiceCliente = -1;
int indiceImovel = -1;
int indiceVenda = -1;

int menu();
void cadastraCliente();
void listarCliente();
void buscaCliente();
void removeCliente();
void atualizarCliente();

void cadastraImovel();
void listarImovel();
void realizarVenda();
void listarVenda();
void calcularTotalVendas();
void listarDoisMaisCaros();

int naoExisteClienteCadastrado(int codigo);

void carregaArquivos();
void salvaArquivos();
void registraAuditoriaCliente(Cliente cliente, char operacao);

int main(){
    //Chamada para ler arquivos com dados
    carregaArquivos();
    puts("Imobiliaria");

    int opcao = -1;

    while (opcao != 0){
        opcao = menu();

        switch(opcao){
        case 1:
            cadastraCliente();
            break;
        case 2:
            listarCliente();
            break;
        case 3:
            cadastraImovel();
            break;
        case 4:
            listarImovel();
            break;
        case 5:
            realizarVenda();
            break;
        case 6:
            listarVenda();
            break;
        case 7:
            calcularTotalVendas();
            break;
        case 8:
            listarDoisMaisCaros();
            break;
        case 9:
            buscaCliente();
            break;
        case 10:
            removeCliente();
            break;
        case 11:
            atualizarCliente();
            break;
        default:
            puts("Opcao invalida!");
            break;
        }

    }
    //Salva arquivos com dados
    salvaArquivos();
}

int menu(){
    int opcao;
    puts("Menu");
    puts(" 1  - Cadastrar Cliente");
    puts(" 2  - Listar Cliente");
    puts(" 3  - Cadastrar Imovel");
    puts(" 4  - Listar Imovel");
    puts(" 5  - Realizar venda");
    puts(" 6  - Listar venda");
    puts(" 7  - Total de vendas em R$");
    puts(" 8  - Listar os 2 imoveis mais caros");
    puts(" 9  - Buscar Cliente");
    puts(" 10 - Remover Cliente");
    puts(" 11 - Atualizar Cliente");
    puts(" 0  - Sair do Sistema");
    scanf("%d", &opcao);
    return opcao;
}

void atualizarCliente(){
     int codigoLido;
    //Posicao encontrada é um valor inválido
    int posicaoEncontrada = -1;

    puts("Digite o codigo do cliente que se quer remover:");
    scanf("%d", &codigoLido);
    int i;
    for(i = 0 ; i <= indiceCliente ; i++){
        if (clientes[i].codigo == codigoLido){
            posicaoEncontrada = i;
        }
    }

    int j;
    //Se posicao for valida, atualizar
    if (posicaoEncontrada != -1){

        //Atualizacao de fato
        puts("Digite o NOVO nome do cliente");
        fflush(stdin);
        getchar();
        fgets(clientes[posicaoEncontrada].nome, 49, stdin);

        //Depois de atualizar o cliente de fato, registrar na auditoria
        registraAuditoriaCliente(clientes[posicaoEncontrada], 'A');

    }else{
        puts("Cliente nao cadastrado");
    }
}

void buscaCliente(){
    int codigoLido;
    //Posicao encontrada é um valor inválido
    int posicaoEncontrada = -1;

    puts("Digite o codigo do cliente que se quer buscar:");
    scanf("%d", &codigoLido);
    int i;
    for(i = 0 ; i <= indiceCliente ; i++){
        if (clientes[i].codigo == codigoLido){
            posicaoEncontrada = i;
            break;
        }
    }

    if (posicaoEncontrada != -1){
        printf("Nome do cliente procurado: %s\n", clientes[posicaoEncontrada].nome);
    }else{
        puts("Cliente nao cadastrado");
    }

}

void removeCliente(){
    int codigoLido;
    //Posicao encontrada é um valor inválido
    int posicaoEncontrada = -1;

    puts("Digite o codigo do cliente que se quer remover:");
    scanf("%d", &codigoLido);
    int i;
    for(i = 0 ; i <= indiceCliente ; i++){
        if (clientes[i].codigo == codigoLido){
            posicaoEncontrada = i;
        }
    }

    int j;
    //Se posicao for valida, excluir
    if (posicaoEncontrada != -1){
        //Antes de excluir o cliente de fato, registrar na auditoria
        registraAuditoriaCliente(clientes[posicaoEncontrada], 'E');

        //Exclusao de fato
        for(j = posicaoEncontrada ; j <= indiceCliente; j++){
            clientes[j] = clientes[j + 1];
        }

        indiceCliente--;
    }else{
        puts("Cliente nao cadastrado");
    }

}

void carregaArquivos(){
    //Variaveis de arquivo
    FILE *arquivo2;

    Cliente clienteLido;

    if((arquivo2 = fopen("cliente.dat","rb")) == NULL){
        printf("Erro ao abrir arquivo!!!\n\n");
        return;
    }
    int sucessoLeitura;
    while(!feof(arquivo2)){

        sucessoLeitura = fread(&clienteLido,sizeof(Cliente),1,arquivo2);

        //Se ler indevidamente,, sucessoLeitura eh igual a zero.
        //Se nao houvesse o if, o programa colocaria mais um item no vetor, repetindo o sempre o ultimo.
        //A inexistencia deste if nao impacta na nota do trabalho, embora deixe o programa incorreto. =]
        if (sucessoLeitura){
            //Incrementa indice de cliente
            indiceCliente++;
            //Coloca cliente lido do arquivo no vetor de clientes
            clientes[indiceCliente] = clienteLido;
        }
    }
    //printf("indiceCliente = %d\n", indiceCliente);

    fclose(arquivo2);

    //Aqui embaixo viriam os outros arquivos (de imovel e de venda)

}

void salvaArquivos(){
    //Variaveis de arquivo
    FILE *arquivo;

    //Abre o arquivo para escrita binaria
    if((arquivo = fopen("cliente.dat","wb")) == NULL){
        printf("Erro ao abrir arquivo!!!\n\n");
        return;
    }

    //Percorre vetor e escreve clientes do vetor no arquivo
    int i;
    for(i = 0 ; i <= indiceCliente; i++){

        fwrite(&clientes[i], sizeof(Cliente), 1, arquivo);
        //printf("Nome do cliente salvo: %s", clientes[i].nome);
    }

    fclose(arquivo);

    //Aqui embaixo viriam os outros arquivos (de imovel e de venda)



}

void registraAuditoriaCliente(Cliente cliente, char operacao){
    FILE *arquivo;

    //Abre o arquivo para escrita
    if((arquivo = fopen("auditoria.txt","a")) == NULL){
        printf("Erro ao abrir arquivo!!!\n\n");
        return;
    }
    fprintf(arquivo, "Entidade: Cliente | Operacao: %c | Codigo_Cliente: %d | Nome_Cliente: %s", operacao, cliente.codigo, cliente.nome);

    fclose(arquivo);
}

void listarDoisMaisCaros(){
    int i, caro1 = 0, caro2 = 0;
    if (indiceImovel== -1 ){
        puts("Nao existem imoveis cadastrados");
        return;
    }

    for (i = 0 ; i <= indiceImovel ; i++){
        if (imoveis[i].preco > imoveis[caro1].preco ){
            caro1 = i;
        }
    }

    for (i = 0 ; i <= indiceImovel ; i++){
        if (i != caro1 && imoveis[i].preco > imoveis[caro2].preco ){
            caro2 = i;
        }
    }

    printf("%s custa R$%f\n", imoveis[caro1].nome, imoveis[caro1].preco);
    printf("%s custa R$%f\n", imoveis[caro2].nome, imoveis[caro2].preco);
}

void calcularTotalVendas(){
    float total = 0;
    int i, j;
    if (indiceVenda == -1 ){
        puts("Nao existem vendas realizadas ");
        return;
    }
    for (i = 0 ; i <= indiceVenda ; i++){
        for (j = 0 ; j <= indiceImovel ; j++){
            if (imoveis[j].codigo == vendas[i].codigo_imovel){
                total = total + imoveis[j].preco;
                break;
            }
        }
    }
    printf("Total de vendas eh: %f\n", total);
}

void listarVenda(){
    int i;
    if (indiceVenda == -1 ){
        puts("Nao existem vendas realizadas ");
    }
    for (i = 0 ; i <= indiceVenda ; i++){
        printf("Codigo do cliente: %d\n", vendas[i].codigo_cliente);
        printf("Codigo do imovel: %d\n", vendas[i].codigo_imovel);
        printf("Valor da entrada: %f\n", vendas[i].entrada);

    }

}

int naoExisteClienteCadastrado(int codigo){
    int naoExisteCliente = 1;
    int i;
    for (i = 0 ; i <= indiceCliente ; i++){
        if (clientes[i].codigo == codigo){
            naoExisteCliente = 0;
            break;
        }
    }
    return naoExisteCliente;
}

void realizarVenda(){
    if (indiceVenda == TAMANHO - 1){
        puts("Nao eh possivel cadastrar mais vendas");
        return;
    }

    //Ler codigo de cliente
    Venda venda;
    puts("Digite o codigo do cliente");
    scanf("%d", &venda.codigo_cliente);

    //Cliente nao existente
    if (naoExisteClienteCadastrado(venda.codigo_cliente)){
        puts("Cliente nao existente");
        return;
    }

    //Ler codigo de imovel
    puts("Digite o codigo do imovel");
    scanf("%d", &venda.codigo_imovel);

    //Imovel nao existente
    int existeImovel = 0;
    int i;
    for (i = 0 ; i <= indiceImovel ; i++){
        if (imoveis[i].codigo == venda.codigo_imovel){
            existeImovel = 1;
            break;
        }
    }
    if (existeImovel == 0){
        puts("Imovel nao existente");
        return;
    }




    puts("Digite o valor da entrada");
    scanf("%f", &venda.entrada);

    indiceVenda++;
    vendas[indiceVenda] = venda;

}

void cadastraCliente(){
    if (indiceCliente == TAMANHO - 1){
        puts("Nao eh possivel cadastrar mais clientes");
        return;
    }

    indiceCliente++;
    Cliente cliente;
    puts("Digite o codigo do cliente");
    scanf("%d", &cliente.codigo);
    puts("Digite o nome do cliente");
    fflush(stdin);
    getchar();
    fgets(cliente.nome, 49, stdin);

    //Codigo para teste
    //printf("Codigo lido do teclado: %d\n", cliente.codigo);
    //printf("Nome lido do teclado: %s\n", cliente.nome);

    //Antes de incluir o cliente de fato, registrar na auditoria
    registraAuditoriaCliente(cliente, 'I');

    clientes[indiceCliente] = cliente;




}

void listarCliente(){
    int i;
    if (indiceCliente == -1 ){
        puts("Nao existem clientes cadastrados");
    }

    for (i = 0 ; i <= indiceCliente ; i++){
        printf("Codigo do cliente: %d\n", clientes[i].codigo);
        printf("Nome do cliente: %s\n", clientes[i].nome);
    }
}

void cadastraImovel(){
    if (indiceImovel == TAMANHO - 1){
        puts("Nao eh possivel cadastrar mais imoveis");
        return;
    }

    indiceImovel++;
    Imovel imovel;
    puts("Digite o codigo do imovel");
    scanf("%d", &imovel.codigo);
    puts("Digite o nome do imovel");
    fflush(stdin);
    getchar();
    fgets(imovel.nome, 49, stdin);
    fflush(stdin);
    puts("Digite o preco do imovel");
    scanf("%f", &imovel.preco);

    //Codigo para teste
    //printf("Codigo lido do teclado: %d\n", cliente.codigo);
    //printf("Nome lido do teclado: %s\n", cliente.nome);

    imoveis[indiceImovel] = imovel;


}

void listarImovel(){
    int i;
    if (indiceImovel == -1 ){
        puts("Nao existem imoveis cadastrados");
    }
    for (i = 0 ; i <= indiceImovel ; i++){
        printf("Codigo do imovel: %d\n", imoveis[i].codigo);
        printf("Nome do imovel: %s\n", imoveis[i].nome);
        printf("Preco do imovel: %f\n", imoveis[i].preco);
    }

}
